﻿/******************************************************************** 
 * Cerebrum Embedded System Design Automation Framework
 * Copyright (C) 2010  The Pennsylvania State University
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ********************************************************************/
//////////////////////////////////////////////////
//
//file name : JProgrammer.cs
//
//Created by: Abdul Abumurad
//
//Date : 25 April 2010
//
//Updated : 
// >> (23 Aug 2010) Abdulrahman Abumurad: Added class name and method name to exception messages generated.
// >> (18 Aug 2010) Matthew Cotter: Updated iMPACT and XMD programming functions to create and run shell scripts to run their corresponding programs.
//                                      The output of these programs are redirected to log files, and downloaded, parsed and saved in the output folder.
//                                      The parsing of the file is to determine whether the programming has been successful.
// >> (21 Jul 2010) Matthew Cotter: Verified that XML-generated Documentation is current.
// >> ( 5 Jul 2010) Matthew Cotter: Significant internal changes made to JProgrammer class in order to support correct identification and programming of target board.
//          16 May 2010 adding clearCMDfile() and ClearTCLfile() methods
//          15 May 2010 adding parsing method.
//          5 May 2010 script file format
//          30 April adding JP commands as methods
//////////////////////////////////////////////////


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using Tamir.SharpSsh;
using FalconGlobal;
using CerebrumSharedClasses;

namespace FalconJTAG_Programmer
{
    /// <summary>
    ///  class is used to connect to programming
    ///  server. to program FPGAs
    /// </summary>
    /// <seealso href="https://www.cse.psu.edu/svn/mdl/falcon_repository/trunk/Software/Cerebrum/Documentation/JProgrammer Specification.pdf">
    /// JProgrammer Documentation</seealso>
    public class JProgrammer : IFalconLibrary
    {

        /// <summary>
        /// Event fired when a message has been generated by the library
        /// </summary>
        public event MessageEventDelegate MessageEvent;
        /// <summary>
        /// Raises an event indicating that a message has been generated.
        /// </summary>
        /// <param name="Message">The message to be transmitted</param>
        /// <param name="Args">List of replacements for token placeholders in the message.</param>
        public void RaiseMessageEvent(string Message, params object[] Args)
        {
            string outputText = Message;
            for (int i = 0; i < Args.Length; i++)
            {
                if (Args[i] != null)
                {
                    outputText = outputText.Replace("{" + i.ToString() + "}", Args[i].ToString());
                }
                else
                {
                    outputText = outputText.Replace("{" + i.ToString() + "}", string.Empty);
                }
            }
            if (MessageEvent != null)
            {
                MessageEvent(outputText);
            }
            else
            {
                Console.WriteLine(outputText);
            }
        }


        #region Properties & Private Members
        /// <summary>
        /// enum for Operating system version
        /// </summary>
        public enum OSVersion 
        { 
            /// <summary>
            /// Microsoft Windows-based Operating System
            /// </summary>
            WINDOWS = 1, 
            /// <summary>
            /// Linux-based Operating System
            /// </summary>
            LINUX = 2 
        };
        /// <summary>
        /// processor type used in either power PC or MicroBlaze
        /// </summary>
        public enum ProcessorType 
        {
            /// <summary>
            /// PowerPC processor.
            /// </summary>
            PPC = 1, 
            /// <summary>
            /// MicroBlaze processor.
            /// </summary>
            MB = 2 
        };

        //
        // Defining Global Object
        //

        /// <summary>
        /// read and write from ssh connection
        /// </summary>
        private SshStream sshStream;
        /// <summary>
        /// execute linux and unix commands
        /// </summary>
        private SshExec execShell; 
        /// <summary>
        ///  to start iMPACT using this shell
        /// </summary>
        private SshShell impactShell;
        /// <summary>
        /// used to start xmd.
        /// </summary>
        private SshShell xmdShell;
        /// <summary>
        /// used ftp to securly copy files from and to remote
        /// server.
        /// </summary>
        private Scp scpShell;
        ///// <summary>
        ///// thread class used for initiating and starting a thread
        ///// </summary>
        //private Thread CommunicatingThread;

        /// <summary>
        /// parameters used to connect to remote server
        /// </summary>
        private string _Username;
        /// <summary>
        /// ste get Mothods for _Username
        /// </summary>
        public string Username
        {
            set
            {
                _Username = value;
            }
            get
            {
                return _Username;
            }
        }
        /// <summary>
        /// holds user password
        /// </summary>
        private string  _UserPass;
        /// <summary>
        /// only set method lfor _UserPass
        /// </summary>
        public string UserPass
        {
            set
            {
                _UserPass = value;
            }
        }
        /// <summary>
        /// holds Servers name to connect to
        /// </summary>
        private string _Servername;
        /// <summary>
        /// set get mothods for _Servername
        /// </summary>
        public string Servername
        {
            get
            {
                return _Servername;
            }
            set
            {
                _Servername = value;
            }
        }
        /// <summary>
        /// when true CommunicationThread
        /// will abort.
        /// </summary>
        public bool StopFlag = false; 
        /// <summary>
        /// flag is used to check if there is a command from user
        /// </summary>
        public  bool isCommand = false; 
        /// <summary>
        /// true if there is a message available to user
        /// </summary>
        public bool isMessage = false;
        /// <summary>
        /// true if server connected
        /// </summary>
        private bool servConnected = false;
        /// <summary>
        /// determine if JTAGs obtained manually already
        /// </summary>
        public bool isJTAGsManual = false;
        /// <summary>
        /// true if the programming server is local
        /// </summary>
        private bool _isLocalProgrammer;
        /// <summary>
        /// set get mothods to modify _isLocalProgrammer
        /// </summary>
        public bool isLocalProgrammer
        {
            set
            {
                _isLocalProgrammer = value;
            }
            get
            {
                return _isLocalProgrammer;
            }
        }
        /// <summary>
        /// takes user permission to create a Directory
        /// if not exist locally or Remotly.
        /// used with Set_local_Dir() and Set_remote_Dir()
        /// methods
        /// </summary>
        private bool _createFolder_ifNotExist = false;
        /// <summary>
        /// set get methods for _createFolder_ifNotExist data member
        /// </summary>
        public bool createFolder_ifNotExist
        {
            get
            {
                return _createFolder_ifNotExist; 
            }
            set
            {
                _createFolder_ifNotExist = value;
            }
        }
        /// <summary>
        /// take oermission to over write files
        /// when copy_File_TO() amd Copy_File_From()
        /// </summary>
        private bool _overWriteFiles = false;
        /// <summary>
        /// set get mothods for _overWriteFiles
        /// </summary>
        public bool overWriteFiles
        {
            get
            {
                return _overWriteFiles;
            }
            set
            {
                _overWriteFiles = value;
            }
        }
        /// <summary>
        /// holds user command
        /// </summary>
        public string command = ""; 
        /// <summary>
        /// holds a message to user
        /// </summary>
        public string retMessage = "";
        /// <summary>
        /// remote Directory from/to which files are copied
        /// </summary>
        public string remoteDir = "";
        /// <summary>
        /// local direcory from/to which files are copied
        /// </summary>
        public  string localDir = "";
        /// <summary>
        /// hold cmd file body of commands
        /// </summary>
        public string CmdFile = "";
        /// <summary>
        /// Holds init file body of commands
        /// </summary>
        public string InitFile = "";
        /// <summary>
        /// holds .cmd file name
        /// </summary>
        private string _cmdFileName = "";
        /// <summary>
        /// Get or set the name of the CMD File to be generated
        /// </summary>
        public string cmdFileName
        {
            get
            {
                return _cmdFileName;
            }
            set
            {
                _cmdFileName = value;
            }
        }
        private string _tclFileName = "";
        /// <summary>
        /// Get or set the name of the TCL File to be generated
        /// </summary>
        public string tclFileName
        {
            get
            {
                return _tclFileName;
            }
            set
            {
                _tclFileName = value;
            }
        }
        private string _bitFileName = "";
        /// <summary>
        /// Get or set the name of the BIT file to be programmed
        /// </summary>
        public string bitFileName
        {
            get
            {
                return _bitFileName;
            }
            set
            {
                _bitFileName = value;
            }
        }
        private string _elfFileName = "";
        /// <summary>
        /// Get or set the name of the ELF file to be programmed
        /// </summary>
        public string elfFileName
        {
            get
            {
                return _elfFileName;
            }
            set
            {
                _elfFileName = value;
            }

        }
        private string _impactModeOpt = "";
        /// <summary>
        /// Get or set the Impact Mode Option
        /// </summary>
        public string impactModeOpt
        {
            get
            {
                return _impactModeOpt;
            }
            set
            {
                _impactModeOpt = value;
            }
        }
        private string _impactCableOpt = "";
        /// <summary>
        /// Get or set the Impact Cable Option
        /// </summary>
        public string impactCableOpt
        {
            get
            {
                return _impactCableOpt;
            }
            set
            {
                _impactCableOpt = value;
            }
        }
        private string _ProcessorOpt = "";
        /// <summary>
        /// Get or set the Processor Option
        /// </summary>
        public string ProcessorOpt
        {
            get
            {
                return _ProcessorOpt;
            }
            set
            {
                _ProcessorOpt = value;
            }
        }
        private uint _JTAG = 0;
        /// <summary>
        /// Get or set the JTAG Number to be programmed
        /// </summary>
        public uint JTAG
        {
            get
            {
                return _JTAG;
            }
            set
            {
                _JTAG = value;
            }
        }
        private OSVersion _localOSType;
        /// <summary>
        /// Get or set the Local OS Type
        /// </summary>
        public  OSVersion localOSType
        {
            get
            {
                return _localOSType;
            }
            set
            {
                _localOSType = value;
            }
    
        }
        private OSVersion _remoteOSType;
        /// <summary>
        /// Get or set the Remote OS Type
        /// </summary>
        public OSVersion remoteOSType
        {
            get
            {
                return _remoteOSType;
            }
            set
            {
                _remoteOSType = value;
            }

        }
        private ProcessorType _PCType;
        /// <summary>
        /// Get or set the Processor Type
        /// </summary>
        public ProcessorType PCType
        {
            set
            {
                _PCType = value;
            }
            get
            {
                return _PCType;
            }
        }

        /// <summary>
        /// Get or set the Cable Port
        /// </summary>
        public string CablePort { get; set; }
        /// <summary>
        /// Get or set the Cable Type
        /// </summary>
        public string CableType { get; set; }

        #endregion

        /// <summary>
        /// initialize CommunicationThread object
        /// Constructor
        /// </summary>
        public JProgrammer()
        {
            StopFlag = false; // stop thread when needed
            isCommand = false; // true if there is a command waiting
            isMessage = false; // true if there is a message available to user
            servConnected = false; // true if server connected
            command = ""; // holds user command
            retMessage = ""; // holds a message to user
        }
        
        #region Methods

        /// <summary>
        /// Executes a shell command on the remote system, if connected.
        /// </summary>
        /// <param name="Command">The command to execute.</param>
        public void Exec(string Command)
        {
            try
            {
                if (execShell.Connected)
                    execShell.RunCommand(Command);
                else
                    RaiseMessageEvent("Could not execute command '{0}'.  Not connected to remote SSH Server.", Command);
            }
            catch //(Exception ex)
            {
                RaiseMessageEvent("An error occured executing remote command: {0}", Command);
            }
        }

        /// <summary>
        ///  starts new thread, start execShell, impactShell,scpShell
        ///  and connects to a server
        /// </summary>
        /// <param name="server">server url</param>
        /// <param name="username">user name</param>
        /// <param name="userpass"> user password</param>
        public void StartThread(string server, string username, string userpass)
        {
            //// new stream shell
            //sshStream = new SshStream(server, username, userpass);
            ////starting impact
            //impactShell = new SshShell(server, username, userpass);
            //RaiseMessageEvent("Connecting to "+server +" please wait...");
            //impactShell.Connect();
            //RaiseMessageEvent("Connected to Server : " + server + "\n");
            //impactShell.WriteLine("impact -batch");
            //RaiseMessageEvent("Strting iMPACT on remote server ...");
            //impactShell.Expect(">");
            //RaiseMessageEvent("iMPACT started on remote Server \n");
            ////starting xmd
            //xmdShell = new SshShell(server, username, userpass);
            //RaiseMessageEvent("Connecting to " + server + " please wait...");
            //xmdShell.Connect();
            //RaiseMessageEvent("Connected to Server : " + server + "\n");
            //xmdShell.WriteLine("xmd");
            //RaiseMessageEvent("Strting XMD on remote server ...");
            //xmdShell.Expect("xmd%");
            //RaiseMessageEvent("XMD started on remote Server \n");
            //// starting execution shell
            //execShell = new SshExec(server, username, userpass);
            //RaiseMessageEvent("Connecting to execution Shell please wait ...");
            //execShell.Connect();
            //RaiseMessageEvent("execution Shell started ..\n");
            //scpShell = new Scp(server, username, userpass);
            //scpShell.Connect();
            //this.Username = username;
            //this.UserPass = userpass;
            //this.Servername = server;
            //CommunicatingThread = new Thread(new ThreadStart(threadCore));
            //CommunicatingThread.Start();

        }

        /// <summary>
        /// log in to remote server
        /// establish SSH connections
        /// </summary>
        /// <exception cref="Exception">Thrown if required login information is not specified.</exception>
        public void login()
        {
            if (_Username == "" || _UserPass == "" || _Servername == "")
            {
                RaiseMessageEvent("JProgrammer:Login(): either one of the following attributes is not set, UserName, Userpassword or servername");
                return;
            }

            sshStream = new SshStream(_Servername, _Username, _UserPass);
            execShell = new SshExec(_Servername,_Username,_UserPass);
            execShell.Connect();
            impactShell = new SshShell(_Servername, _Username, _UserPass);
            impactShell.Connect();
            xmdShell = new SshShell(_Servername, _Username, _UserPass);
            xmdShell.Connect();
            scpShell = new Scp(_Servername, _Username, _UserPass);
            scpShell.Connect();
            servConnected = true;

            if (!execShell.Connected)
            {
                RaiseMessageEvent("JProgrammer:Login():Failed to login! check username, password and Server name");
                return;
            }


        }

        /// <summary>
        /// release all connections and logout remote server
        /// </summary>
        public void logout()
        {
            if(execShell.Connected)
            {
                execShell.Close();
                sshStream.Close();
                impactShell.Close();
                xmdShell.Close();
                scpShell.Close();
                servConnected = false;
            }
        }

        /// <summary>
        /// Returns impact command to clean programming cable 
        /// locks
        /// </summary>
        /// <returns> command string to clean impact cable</returns>
        public void Clean_iMPACT_Cable()
        {
            CmdFile += "cleancablelock\n";
        }

        /// <summary>
        /// this method genetares necessary commands
        /// to clean xmd load cable
        /// </summary>
        /// <returns>command string</returns>
        public void Clean_XMD_Cable()
        {
            InitFile += "xclean_cablelock\n";
        }

        /// <summary>
        /// Sets local directory that will be used to copy from or
        /// to it. project dorectory
        /// </summary>
        /// <param name="localPath"> local Directory Path, passed by User</param>
        /// <returns>returns true if it is successful</returns>
        /// <exception cref="Exception">Thrown if directory path does not exist or is invalid for the local OS.</exception>
        public bool Set_Local_Dir(string localPath)
        {
            if (!System.IO.Directory.Exists(localPath))
            {
                RaiseMessageEvent("JProgrammer:Set_local_Dir():Selected Directory is not exist");
                return false;
            }
            if (_localOSType == OSVersion.WINDOWS)
            {
                if (localPath.Contains("/"))
                {
                    RaiseMessageEvent("JProgrammer:Set_local_Dir():illegal Windows directory Path provided");
                    return false;
                }

                else
                {
                    localDir = localPath;
                    return true;
                }
            }
            else if (_localOSType == OSVersion.LINUX)
            {
                if (localPath.Contains("\\"))
                {
                    RaiseMessageEvent("JProgrammer:Set_local_Dir():illegal linux or Unix directory Path provided");
                    return false;
                }
                else
                {
                    localDir = localPath;
                }
            }
            return false;
        }

        /// <summary>
        /// Sets Remote directory that will be used to copy from or
        /// to it. Destination project directory
        /// </summary>
        /// <param name="remotePath"> remote Directory Path, passed by User</param>
        /// <returns>returns true if it is successful</returns>
        /// <exception cref="Exception">Thrown if if directory path does not exist or is invalid for the remote OS.</exception>
        public bool Set_Remote_Dir(string remotePath)
        {
            if (_isLocalProgrammer)
            {
                RaiseMessageEvent("JProgrammer:Set_Remote_Dir():Local Programming Server does not require remote Directory");
                return false;
            }
            if(!servConnected)
            {
                RaiseMessageEvent("JProgrammer:Set_Remote_Dir():remote Server is not connected, Server should beconnected to verify remote Directory");
                return false;
            }
            if(remotePath != "")
            {
                string parentDir = remotePath.Substring(0, remotePath.LastIndexOf((_remoteOSType == OSVersion.WINDOWS) ? "\\" : "/"));
                string targetDir = remotePath.Substring(remotePath.LastIndexOf((_remoteOSType == OSVersion.WINDOWS) ? "\\" : "/") + 1);
                string resp = execShell.RunCommand("ls " + parentDir);
                if (!resp.Contains(targetDir))
                {
                    if (createFolder_ifNotExist)
                    {
                        execShell.RunCommand("mkdir " + remotePath);
                        resp = execShell.RunCommand("ls " + parentDir);
                        if (!resp.Contains(targetDir))
                        {
                            RaiseMessageEvent("JProgrammer:Set_Remote_Dir():Selected Remote Directory could not be created");
                            return false;
                        }
                        else 
                        {                            
                            remoteDir = remotePath;
                            return true;
                        }
                    }
                    else
                    {
                        RaiseMessageEvent("JProgrammer:Set_Remote_Dir():Selected Remote Directory is not exist");
                        return false;
                    }
                }
            }
            if (_remoteOSType == OSVersion.WINDOWS)
            {
                if (remotePath.Contains("/"))
                {
                    RaiseMessageEvent("JProgrammer:Set_Remote_Dir():illegal Windows directory Path provided");
                    return false;
                }
                else
                {
                    remoteDir = remotePath;
                    return true;
                }
            }
            else if (_remoteOSType == OSVersion.LINUX)
            {
                if (remotePath.Contains("\\"))
                {
                    RaiseMessageEvent("JProgrammer:Set_Remote_Dir():illegal linux or Unix directory Path provided");
                    return false;
                }
                else
                {
                    remoteDir = remotePath;
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// copy a file from local Directory set in LocalDir variable
        /// to Remote Directory found in RemoteDir variable
        /// if localDir and/or remoteDir not set throws exception
        /// if local Directory is not exist throws exception
        /// if file is not present in local Directory throes exception
        /// </summary>
        /// <param name="fileName"> file name to be copied to remote directory</param>
        /// <returns>returns true if copy operation is done successfuly else returns false</returns>
        /// <exception cref="Exception">Thrown if the file does not exist, the remote server is not connected, or either local or remote directory is not set.</exception>
        public bool Copy_File_To(string fileName)
        {
           if(_isLocalProgrammer)
           {
               RaiseMessageEvent("JProgrammer:Copy_File_To():Copy_File_to() command connect be used locally");
               return false;
           }
           if(!servConnected)
           {
               RaiseMessageEvent("JProgrammer:Copy_File_To():Remote server is not connected, Please login() command");
               return false;
           }
           if(localDir == "" || remoteDir == "")
           {
               RaiseMessageEvent("JProgrammer:Copy_File_To():either Local Directory or Remote Directory is not set. use sld or srd commands");
               return false;
           }
           if(!System.IO.Directory.Exists(localDir))
           {
               RaiseMessageEvent("JProgrammer:Copy_File_To():Given Path is not exist, please check local Directory before usage");
               return false;
           }
           if(! _overWriteFiles)
           {
               string resp = execShell.RunCommand("ls "+remoteDir+"/"+fileName);
               if (resp.Replace("\n","") == remoteDir + "/" + fileName)
               {
                   RaiseMessageEvent("JProgrammer:Copy_File_To(): " +fileName + " Already exist, OverWrite OPtion is set to False. to overWirte desitnation file set _overWriteFiles = true");
                   return false;
               }
           }
           {
               bool found = false;
               string[] dirFiles = System.IO.Directory.GetFiles(localDir);
               foreach (string file in dirFiles)
               {
                   string tempFile = file.Replace(localDir+"\\","");
                   if (tempFile == fileName)
                   {
                       found = true;
                       break;
                   }
               }
               if (found)
               {
                   if (_remoteOSType == OSVersion.WINDOWS)
                       scpShell.To(localDir + "\\" + fileName, remoteDir + "\\" + fileName);
                   else if (_remoteOSType == OSVersion.LINUX)
                       scpShell.To(localDir + "\\" + fileName, remoteDir + "/" + fileName);

                   return true;
               }
               else
               {
                   RaiseMessageEvent("JProgrammer:Copy_File_To():File name is not found in local Directory provided");
                   return false;
               }
           }
           //return false;
        }

        /// <summary>
        /// move the whole directory from local machine to remote machine
        /// check if both localDir and remoteDir varable are set.
        /// check is local directory provided is exit. 
        /// </summary>
        /// <returns>true if copy is done successfully else returns false</returns>
        /// <exception cref="Exception">Thrown if the directory does not exist, the remote server is not connected, or either local or remote directory is not set.</exception>
        public bool Copy_Dir_To()
        {
            if (_isLocalProgrammer)
            {
                RaiseMessageEvent("JProgrammer:Copy_Dir_To():Copy_File_to() command connect be used locally");
                return false;
            }
            if (!servConnected)
            {
                RaiseMessageEvent("JProgrammer:Copy_Dir_To():Remote server is not connected, Please login() command");
                return false;
            }

            if (localDir == "" || remoteDir == "")
            {
                RaiseMessageEvent("JProgrammer:Copy_Dir_To():either Local Directory or Remote Directory is not set. use set_local_dir() or set_remote_dir() commands");
                return false;
            }
            else if(! _createFolder_ifNotExist)
            {
                // check if local Directory exist or not
                if (!System.IO.Directory.Exists(localDir))
                {
                    RaiseMessageEvent("JProgrammer:Copy_Dir_To():Local Directory is not exist, please use set_local_dir() command to provide a valid directory path,\n or use createFolder_ifNotExist option to create it if not exist?");
                    return false;
                }
                // check the remote directory existance
                if( ! _isLocalProgrammer)
                {
                    string resp = execShell.RunCommand("ls "+remoteDir);
                    if (resp == "")
                    {
                        RaiseMessageEvent("JProgrammer:Copy_Dir_To():Remote Directory is not exist, please use set_remote_dir() command to provide a valid directory path,\n or use createFolder_ifNotExist option to create it if not exist?");
                        return false;
                    }
                }
            }
            else
            {          
                scpShell.To(localDir, remoteDir, true);
                return true;
            }
            return false;
        }

        /// <summary>
        /// copy a file from remote Directory set in remoteDir variable
        /// to local Directory found in localDir variable
        /// if localDir and/or remoteDir not set throws exception
        /// if local Directory is not exist throws exception
        /// if file is not present in remote Directory throws exception
        /// </summary>
        /// <param name="fileName"> file name to be copied to remote directory</param>
        /// <returns>returns true if copy operation is done successfuly else returns false</returns>
        /// <exception cref="Exception">Thrown if the file does not exist, the remote server is not connected, or either local or remote directory is not set.</exception>
        public bool Copy_File_From(string fileName)
        {
            if (_isLocalProgrammer)
            {
                RaiseMessageEvent("JProgrammer:Copy_File_From():Copy_File_to() command connect be used locally");
                return false;
            }
            if (!servConnected)
            {
                RaiseMessageEvent("JProgrammer:Copy_File_From():Remote server is not connected, Please login() command");
                return false;
            }
            if (localDir == "" || remoteDir == "")
            {
                RaiseMessageEvent("JProgrammer:Copy_File_From():either Local Directory or Remote Directory is not set. use sld or srd commands");
                return false;
            }
            if (!System.IO.Directory.Exists(localDir))
            {
                RaiseMessageEvent("JProgrammer:Copy_File_From():Given local Path is not exist, please check local Directory before usage");
                return false;
            }
            if (!_overWriteFiles)
            {
                if ( System.IO.File.Exists(localDir +"\\"+fileName))
                {
                    RaiseMessageEvent("JProgrammer:Copy_File_From(): "+fileName + " Already exist, OverWrite OPtion is set to False. to overWirte desitnation file set _overWriteFiles = true");
                    return false;
                }
            }
            if(_remoteOSType == OSVersion.LINUX)
            {
                string FullFilePath = remoteDir + "/" + fileName;
                string resp = execShell.RunCommand("ls "+FullFilePath);
                if( ! (resp.Replace("\n","") == FullFilePath))
                {
                    RaiseMessageEvent("JProgrammer:Copy_File_From():Given remote Path is not exist, please check local Directory before usage");
                    return false;
                }
            }
            else if(_remoteOSType == OSVersion.WINDOWS)
            {
               // for future inplementation not for testing
            }
            {
                bool found = false;
                string Response = execShell.RunCommand("cd "+remoteDir);
                Response = execShell.RunCommand("ls " + remoteDir);
                if (Response.Contains(fileName))
                {
                    found = true;
                }
                if (found)
                {
                    if (_remoteOSType == OSVersion.WINDOWS)
                        scpShell.From(remoteDir + "\\" + fileName,localDir + "\\" + fileName );
                    else if (_remoteOSType == OSVersion.LINUX)
                        scpShell.From(remoteDir + "/" + fileName, localDir + "\\" + fileName);
                    return true;
                }
                else
                {
                    RaiseMessageEvent("JProgrammer:Copy_File_From():File name is not found in local Directory provided");
                    return false;
                }
            }
            //return false;
        }

        /// <summary>
        /// move the whole directory from remote machine to local machine
        /// check if both localDir and remoteDir varable are set.
        /// check is local directory provided is exit. 
        /// </summary>
        /// <returns>true if copy is done successfully else returns false</returns>
        /// <exception cref="Exception">Thrown if the directory does not exist, the remote server is not connected, or either local or remote directory is not set.</exception>
        public bool Copy_Dir_From()
        {
            if (_isLocalProgrammer)
            {
                RaiseMessageEvent("JProgrammer:Copy_Dir_From(): Copy_File_to() command connect be used locally");
                return false;
            }
            if (!servConnected)
            {
                RaiseMessageEvent("JProgrammer:Copy_Dir_From(): Remote server is not connected, Please login() command");
                return false;
            }
            if (localDir == "" || remoteDir == "")
            {
                RaiseMessageEvent("JProgrammer:Copy_Dir_From(): either Local Directory or Remote Directory is not set. use sld or srd commands");
                return false;
            }
            else if (!_createFolder_ifNotExist)
            {
                // check if local Directory exit or not
                if (!System.IO.Directory.Exists(localDir))
                {
                    RaiseMessageEvent("JProgrammer:Copy_Dir_From(): Local Directory is not exist, please use set_local_dir() command to provide a valid directory path,\n or use createFolder_ifNotExist option to create it if not exist?");
                    return false;
                }
                // check the remote directory existance
                if (!_isLocalProgrammer)
                {
                    string resp = execShell.RunCommand("ls " + remoteDir);
                    if (resp.Contains("ls:") || resp.Contains(" No such file or directory"))
                    {
                        RaiseMessageEvent("JProgrammer:Copy_Dir_From(): Remote Directory is not exist, please use set_remote_dir() command to provide a valid directory path,\n or use createFolder_ifNotExist option to create it if not exist?");
                        return false;
                    }
                }
            }
            {

                if (_remoteOSType == OSVersion.WINDOWS && remoteDir.Contains("\\"))
                    scpShell.From(remoteDir,localDir , true);
                else if (_remoteOSType == OSVersion.LINUX && remoteDir.Contains("/"))
                    scpShell.From(remoteDir,localDir , true);

                return true;

            }
            //return false;
        }

        
        /// <summary>
        /// generate script to program FPGA connected to
        /// JTAG port.
        /// </summary>
        /// <param name="BIT">The BIT File to download to the FPGA.</param>
        /// <returns>string contains scrip</returns>
        /// <exception cref="Exception">Thrown if the JTAG property is not set.</exception>
        public void DownloadBitFile(string BIT)
        {
            if(_JTAG != 0)
            {
                CmdFile += "setmode -bs\n";
                CmdFile += "setcable -p " + this.CablePort + "\n";
                CmdFile += "identify\n";
                CmdFile += "assignFile -p " + _JTAG + " -file " + BIT + "\n";
                CmdFile += "program -p " + _JTAG + "\n";
                CmdFile += "unlockcable\n";                
            }
            else
            {
                RaiseMessageEvent("JProgrammer:DownloadBitFile(): JTAG is not set to a value, use set JTAG property");
                return;
            }

        }

        /// <summary>
        /// Appends the set of commands needed to download .elf file to the specified processor.
        /// </summary>
        /// <param name="CPU">The CPU Number to be programmed.</param>
        /// <param name="ELF">The ELF File to download to the CPU.</param>
        public void DownloadElfFile(string CPU, string ELF)
        {
            //InitFile += String.Format("connect {0} {1} -cable type {2} port {3} -configdevice {4} {5}\ndow {6}\ndisconnect 0\n",
            InitFile += String.Format("connect {0} {1} -cable type {2} port {3} -debugdevice devicenr {4} cpunr {5}\ndow {6}\n{7}\ndisconnect 0\n",
                        (this.PCType == ProcessorType.PPC ? "ppc" : "mb"),
                        (this.PCType == ProcessorType.PPC ? "hw" : "mdm"),
                        this.CableType,
                        this.CablePort,
                        this.JTAG,
                        CPU,
                        ELF,
                        (this.PCType == ProcessorType.PPC ? "run" : "con"));
        }

        /// <summary>
        /// Creates .cmd file and save it to local
        /// directory specified
        /// </summary>
        /// <exception cref="Exception">Thrown if the local directory is not set.</exception>
        public void Generate_cmd_File()
        {
            if(localDir == "")
            {
                RaiseMessageEvent("JProgrammer:Generate_cmd_File(): Local Directory property is not set to a value");
                return;
            }
            try
            {
                FileInfo file_info = new FileInfo(localDir + "\\" + _cmdFileName);
                StreamWriter sw = file_info.CreateText();
                CmdFile += "exit\n";
                sw.WriteLine(CmdFile);
                sw.Close();
            }
            catch (Exception e)
            {
                RaiseMessageEvent("Jprogrammer:Generate_cmd_File(): " +e.Message);
                return;
            }
        }

        /// <summary>
        /// Creates .ini file and save it to local
        /// directory specified
        /// </summary>
        /// <exception cref="Exception">Thrown if the local directory is not set.</exception>
        public void Generate_tcl_file()
        {
            if (localDir == "")
            {
                RaiseMessageEvent("JProgrammer:Generate_tcl_File(): Local Directory property is not set to a value");
                return;
            }
            try
            {
                FileInfo finfo = new FileInfo(localDir + "\\" + _tclFileName);
                StreamWriter sw = finfo.CreateText();
                InitFile += "exit\n";
                sw.WriteLine(InitFile);
                sw.Close();
            }
            catch (Exception e)
            {
               RaiseMessageEvent("JProgrammer:Generate_tcl_File(): " +e.Message);
               return;
            }

        }

        /// <summary>
        /// run iMPACT with cmd file provided.
        /// </summary>
        /// <param name="PlatformID">The name of the platform currently being programmed, for logfile identification.</param>
        /// <exception cref="Exception">Thrown if the CmdFile property is not set.</exception>
        public bool runImpactProg(string PlatformID)
        {
            if (_cmdFileName == "" || CmdFile == "")
            {
                RaiseMessageEvent("JProgrammer:runImpactProg(): cmd file name is not set or/and cmd file is empty");
                return false;
            }

            if(_isLocalProgrammer)
            {
                System.Diagnostics.ProcessStartInfo ImpactProcessInfo = new System.Diagnostics.ProcessStartInfo("xbash");
                ImpactProcessInfo.RedirectStandardError = true;
                ImpactProcessInfo.RedirectStandardInput = true;
                ImpactProcessInfo.RedirectStandardOutput = true;
                ImpactProcessInfo.UseShellExecute = false;
                ImpactProcessInfo.CreateNoWindow = true;
                System.Diagnostics.Process ImpactProcess = new System.Diagnostics.Process();
                ImpactProcess.StartInfo = ImpactProcessInfo;
                ImpactProcess.Start();
                ImpactProcess.StandardInput.WriteLine("impact -batch " + localDir + "\\" + _cmdFileName);
                ImpactProcess.WaitForExit();
                ImpactProcess.Close();
                return true;
            }
            else
            {
                string completeFlag = "FalconProgramming: iMPACT COMPLETE";
                string impactLog = String.Format("{0}_impact.log", PlatformID);
                string remoteLog = String.Format("{0}{1}", remoteDir, impactLog);
                string localLog = String.Format("{0}\\{1}", localDir, impactLog);

                FileInfo fiShellScript = new FileInfo(String.Format("{0}\\program_bit.sh", localDir));
                string remoteScript = String.Format("{0}{1}", remoteDir, fiShellScript.Name);
                if (fiShellScript.Exists)
                    fiShellScript.Delete();
                StreamWriter writer = new StreamWriter(fiShellScript.FullName);
                writer.Write(String.Format("#!/bin/bash\n"));
                FalconFileRoutines.WriteCerebrumDisclaimer(writer, "# ");   // Added for auto-generated shell script file.
                writer.Write(String.Format("cd {0}\n", remoteDir));
                writer.Write(String.Format("rm {0}\n", impactLog));
                writer.Write(String.Format("impact -batch {0} > {1}\n", _cmdFileName, impactLog));
                writer.Write(String.Format("echo \"{0}\"\n", completeFlag));
                writer.Close();

                scpShell.To(fiShellScript.FullName, remoteScript);

                impactShell.WriteLine(String.Format("chmod 700 {0}", remoteScript));
                impactShell.Expect();
                impactShell.WriteLine(String.Format("sh {0}", remoteScript));
                string CommandResponse = impactShell.Expect(new System.Text.RegularExpressions.Regex(completeFlag));
                if (CommandResponse.Trim().Contains(completeFlag))
                {
                    impactShell.WriteLine(String.Format("rm {0}", remoteScript));
                    scpShell.From(remoteLog, localLog);
                    if (!ParseImpactLog(localLog))
                    {
                        RaiseMessageEvent("\nFAILED!\n\tPlease examine the log file '{0}' for more details.", localLog);
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
                else
                {
                    RaiseMessageEvent("\nFAILED!\n\tAn unknown error occured running iMPACT.\n\tPlease examine the log file '{0}' for more details.", localLog);
                    return false;
                }
            }
        }

        /// <summary>
        /// Examines the output generated by the iMPACT script to determine whether programming was successful or not.
        /// </summary>
        /// <param name="LogPath">The local path to the log file to be examined.</param>
        /// <returns>True if programming was successful; False if programming was unsuccessful or if success is unable to be determined.</returns>
        private bool ParseImpactLog(string LogPath)
        {
            FileInfo fiLog = new FileInfo(LogPath);
            if (fiLog.Exists)
            {
                StreamReader reader = new StreamReader(fiLog.FullName);
                StringBuilder fileContents = new StringBuilder();
                while (!reader.EndOfStream)
                {
                    fileContents.AppendLine(reader.ReadLine());
                }
                reader.Close();

                string contents = fileContents.ToString();
                if (contents.Contains("Programmed successfully."))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        
        /// <summary>
        /// run XMD with ini file provided.
        /// </summary>
        /// <param name="PlatformID">The name of the platform currently being programmed, for logfile identification.</param>
        /// <param name="ProcInstance">The name of the processor instance currently being programmed, for logfile identification.</param>
        /// <exception cref="Exception">Thrown if an error occurs in the connection to the remote system.</exception>
        public bool runXMDProg(string PlatformID, string ProcInstance)
        {
            if (_isLocalProgrammer)
            {
                System.Diagnostics.ProcessStartInfo ImpactProcessInfo = new System.Diagnostics.ProcessStartInfo("xbash");
                ImpactProcessInfo.RedirectStandardError = true;
                ImpactProcessInfo.RedirectStandardInput = true;
                ImpactProcessInfo.RedirectStandardOutput = true;
                ImpactProcessInfo.UseShellExecute = false;
                ImpactProcessInfo.CreateNoWindow = true;
                System.Diagnostics.Process ImpactProcess = new System.Diagnostics.Process();
                ImpactProcess.StartInfo = ImpactProcessInfo;
                ImpactProcess.Start();
                ImpactProcess.StandardInput.WriteLine("xmd -tcl " + localDir + "\\" + _tclFileName);
                ImpactProcess.WaitForExit();
                ImpactProcess.Close();
                return true;
            }
            else
            {
                string completeFlag = "FalconProgramming: XMD COMPLETE";
                string xmdLog = String.Format("{0}_{1}_xmd.log", PlatformID, ProcInstance);
                string remoteLog = String.Format("{0}{1}", remoteDir, xmdLog);
                string localLog = String.Format("{0}\\{1}", localDir, xmdLog);

                FileInfo fiShellScript = new FileInfo(String.Format("{0}\\program_elf.sh", localDir));
                string remoteScript = String.Format("{0}{1}", remoteDir, fiShellScript.Name);
                if (fiShellScript.Exists)
                    fiShellScript.Delete();
                StreamWriter writer = new StreamWriter(fiShellScript.FullName);
                writer.Write(String.Format("#!/bin/bash\n"));
                FalconFileRoutines.WriteCerebrumDisclaimer(writer, "# ");   // Added for auto-generated shell script file.
                writer.Write(String.Format("cd {0}\n", remoteDir));
                writer.Write(String.Format("rm {0}\n", xmdLog));
                writer.Write(String.Format("xmd -tcl {0} > {1}\n", _tclFileName, xmdLog));
                writer.Write(String.Format("echo \"{0}\"\n", completeFlag));
                writer.Close();

                scpShell.To(fiShellScript.FullName, remoteScript);

                impactShell.WriteLine(String.Format("chmod 700 {0}", remoteScript));
                impactShell.Expect();
                impactShell.WriteLine(String.Format("sh {0}", remoteScript));
                string CommandResponse = impactShell.Expect(new System.Text.RegularExpressions.Regex(completeFlag));
                if (CommandResponse.Trim().Contains(completeFlag))
                {
                    impactShell.WriteLine(String.Format("rm {0}", remoteScript));
                    scpShell.From(remoteLog, localLog);
                    if (!ParseXMDLog(localLog))
                    {
                        RaiseMessageEvent("\nFAILED!\nPlease examine the log file '{0}' for more details.", localLog);
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
                else
                {
                    RaiseMessageEvent("\nFAILED!\n\tAn unknown error occured running XMD.\n\tPlease examine the log file '{0}' for more details.", localLog);
                    return false;
                }
            }
        }

        /// <summary>
        /// Examines the output generated by the XMD script to determine whether programming was successful or not.
        /// </summary>
        /// <param name="LogPath">The local path to the log file to be examined.</param>
        /// <returns>True if programming was successful; False if programming was unsuccessful or if success is unable to be determined.</returns>
        private bool ParseXMDLog(string LogPath)
        {
            FileInfo fiLog = new FileInfo(LogPath);
            if (fiLog.Exists)
            {
                StreamReader reader = new StreamReader(fiLog.FullName);
                StringBuilder fileContents = new StringBuilder();
                while (!reader.EndOfStream)
                {
                    fileContents.AppendLine(reader.ReadLine());
                }
                reader.Close();

                string contents = fileContents.ToString();
                if (contents.Contains("Processor started."))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        private bool RunXMDInteractively()
        {
            // Launching XMD to clear cable locks
            impactShell.RemoveTerminalEmulationCharacters = true;
            impactShell.WriteLine("xmd");
            string response = impactShell.Expect("XMD%");
            impactShell.WriteLine("xclean_cablelock");
            response = impactShell.Expect("Cable Locks Removed");
            while (!response.Trim().EndsWith("XMD%"))
                response += impactShell.Expect("XMD%");

            string xmdCommand = string.Empty;
            string procType = string.Empty;
            if (_PCType == ProcessorType.PPC)
            {
                procType = "ppc";
            }
            else if (_PCType == ProcessorType.MB)
            {
                procType = "mb";
            }
            // Connect to processor targets
            string ConnectCommand = String.Format("connect {0} {1} -cable type {2} port {3} -debugdevice devicenr {4} {5}",
                procType,
                ProcessorOpt,
                this.CableType,
                this.CablePort,
                this.JTAG,
                string.Empty);
            //(this.CPUNumber >= 0 ? "cpunr " + this.CPUNumber : string.Empty));

            xmdCommand = "connect " + procType + " " + ProcessorOpt + " -cable type " + this.CableType + " port " + this.CablePort + " -debugdevice devicenr " + this._JTAG;
            impactShell.WriteLine(xmdCommand);
            response = impactShell.Expect(xmdCommand);
            while (!response.Trim().EndsWith("XMD%"))
                response += impactShell.Expect("XMD%");
            // Verify we choose the correct target
            response = response.Replace("\n", string.Empty);
            string[] respLines = response.Split('\r');
            string cablePort = string.Empty;
            string targetID = string.Empty;
            bool bUseNextTarget = false;
            bool bError = false;

            foreach (string line in respLines)
            {
                if (line.Contains("Connecting to cable"))
                {
                    // Extract port from response line
                    cablePort = line.Substring(line.LastIndexOf(' ')).Trim();
                    cablePort = cablePort.Replace(").", string.Empty);
                    if (cablePort.ToLower() == this.CablePort.ToLower())
                    {
                        bUseNextTarget = true;
                    }
                }
                else if ((bUseNextTarget) && (line.Contains("Connected to ")) && (line.Contains(procType)))
                {
                    // This line indicates the target ID we connected to
                    targetID = line.Substring(line.LastIndexOf(' ')).Trim();
                    break;
                }
            }
            //RaiseMessageEvent(response);
            if (targetID != string.Empty)
            {
                // Found a target, select it
                if ((response.Contains("Error")) || (response.Contains("ERROR")))
                    bError = true;
                if (!bError)
                {
                    xmdCommand = "targets " + targetID;
                    impactShell.WriteLine(xmdCommand);
                    response = impactShell.Expect(xmdCommand);
                    while (!response.Trim().EndsWith("XMD%"))
                        response += impactShell.Expect("XMD%");
                }
                //RaiseMessageEvent(response);
                if ((response.Contains("Error")) || (response.Contains("ERROR")))
                    bError = true;
                if (!bError)
                {
                    // Download the ELF file
                    xmdCommand = "dow " + this.elfFileName;
                    impactShell.WriteLine(xmdCommand);
                    response = impactShell.Expect(xmdCommand);
                    while (!response.Trim().EndsWith("XMD%"))
                        response += impactShell.Expect("XMD%");
                }
                //RaiseMessageEvent(response);
                if ((response.Contains("Error")) || (response.Contains("ERROR")))
                    bError = true;
                if (!bError)
                {
                    // Run the ELF file
                    xmdCommand = "run";
                    impactShell.WriteLine(xmdCommand);
                    response = impactShell.Expect(xmdCommand);
                    while (!response.Trim().EndsWith("XMD%"))
                        response += impactShell.Expect("XMD%");
                }
                // Disconnect from the processor (Always execute disconnect)
                xmdCommand = "disconnect " + targetID;
                impactShell.WriteLine(xmdCommand);
                response = impactShell.Expect(xmdCommand);
                while (!response.Trim().EndsWith("XMD%"))
                    response += impactShell.Expect("XMD%");
                //RaiseMessageEvent(response);
                if ((response.Contains("Error")) || (response.Contains("ERROR")))
                    bError = true;
            }
            else
            {
                bError = true;
            }
            // Exit XMD (Always execute clean and Exit)
            xmdCommand = "xclean_cable";
            impactShell.WriteLine(xmdCommand);
            xmdCommand = "exit";
            impactShell.WriteLine(xmdCommand);
            if ((response.Contains("Error")) || (response.Contains("ERROR")) || (bError))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// this method will clear all options
        /// in order to be used again.
        /// </summary>
        public void ClearOptions()
        {
            _Username = "";
            _UserPass = "";
            _Servername = "";
            remoteDir = "";
            localDir = "";
            CmdFile = "";
            _cmdFileName = "";
            InitFile = "";
            _tclFileName = "";
            _bitFileName = "";
            _elfFileName = "";
            _impactModeOpt = "";
            _impactCableOpt = "";
            _ProcessorOpt = "";
            _JTAG = 0;
            _isLocalProgrammer = false;

        }

        /// <summary>
        /// clears cmd file in order to be reused again.
        /// </summary>
        public void ClearCMDfile()
        {
            this.CmdFile = "";
        }

        /// <summary>
        /// clears TCL file in order to be used again
        /// </summary>
        public void ClearTCLfile()
        {
            this.InitFile = "";
        }

        #endregion

        ///// <summary>
        ///// this method is the core of a thread
        ///// will connect to ssh shell and exec shell
        ///// also to programming server.
        ///// thread will commuincate with main interface
        ///// through flags and global varables
        ///// no need for synch since this is the only thread
        ///// return messages through shared variables
        ///// </summary>
        //public void threadCore()
        //{
        //   //while(!StopFlag)
        //   //{
        //   //    if(isCommand)
        //   //    {
        //   //        #region Copy file to command
        //   //        if (this.command == "cft")
        //   //        {
        //   //            if(System.IO.Directory.Exists(this.localDir))
        //   //                scpShell.To(this.localDir, this.remoteDir,true);
        //   //            else
        //   //                scpShell.To(this.localDir, this.remoteDir);
        //   //            RaiseMessageEvent("File " + this.localDir + " copied successfuly to " + this.remoteDir);
        //   //            this.command = "";
        //   //            this.isCommand = false;
        //   //        } 
        //   //        #endregion

        //   //        #region copy file from command
        //   //        if(this.command == "cff")
        //   //        {

        //   //            if (System.IO.Directory.Exists(this.remoteDir))
        //   //                scpShell.From(this.remoteDir, this.localDir,true);
        //   //            else
        //   //                scpShell.From(this.remoteDir, this.localDir);
        //   //            RaiseMessageEvent("File " + this.remoteDir + " copied successfuly to " + this.localDir);
        //   //            this.command = "";
        //   //            this.isCommand = false;
	                 
        //   //        }
        //   //        #endregion
                   
        //   //        #region clear impact cable command
        //   //        if(this.command == "cic")
        //   //        {
                        
        //   //             try
        //   //             {
        //   //                     impactShell.WriteLine("cleancablelock");
        //   //                     impactShell.Expect("Done");
        //   //                     RaiseMessageEvent("iMPACT Locks were released!");                      
                   
        //   //             }
        //   //             catch (Exception e)
        //   //             {
        //   //                 RaiseMessageEvent("make sure that Server name is correct...");
        //   //             }
                       
        //   //             this.isCommand = false;
        //   //             this.command = "";
        //   //        }
        //   //        #endregion

        //   //        #region download bit file
        //   //        if(this.command == "dbs")
        //   //        {
        //   //            try
        //   //            {
                           
        //   //                sshStream.Write("setmode -bs\r");
        //   //                RaiseMessageEvent(sshStream.ReadResponse());
        //   //                //impactShell.WriteLine("");
        //   //                //impactShell.Expect(">");
        //   //                impactShell.WriteLine("setcable -p auto");
        //   //                impactShell.Expect(">");
        //   //                RaiseMessageEvent(sshStream.ReadResponse());
        //   //                impactShell.WriteLine("identify");
        //   //                impactShell.Expect(">");
        //   //                RaiseMessageEvent(sshStream.ReadResponse());
        //   //                this.isCommand = false;
        //   //                this.command = "";
        //   //            }
        //   //            catch(Exception e)
        //   //            {
        //   //                RaiseMessageEvent(e.Message);
        //   //            }
        //   //        }
        //   //        #endregion

        //   //        #region clean xmd Cable
        //   //        if (command == "cxc")
        //   //        {
        //   //            try
        //   //            {
        //   //                xmdShell.WriteLine("xmd");
        //   //                xmdShell.Expect("XMD%");
        //   //                RaiseMessageEvent("XMD started on local machine");
        //   //                xmdShell.WriteLine("xclean_cable");
        //   //                xmdShell.Expect("X Cable Locks Removed");
        //   //                RaiseMessageEvent("X Cable locks Removed");

        //   //            }
        //   //            catch (Exception e)
        //   //            {
        //   //                RaiseMessageEvent(e.Message);
        //   //            }
        //   //        } 
        //   //        #endregion

        //   //        #region exe commands
        //   //        if(command.Contains("exe "))
        //   //        {
        //   //            retMessage = execShell.RunCommand(command.Replace("exe ", ""));
        //   //            isMessage = true;
        //   //        }
        //   //        #endregion

        //   //    }

        //   //}

        //   //execShell.Close();
        //   //impactShell.WriteLine("exit");
        //   //impactShell.Close();
        //   //xmdShell.WriteLine("exit");
        //   //xmdShell.Close();
        //   //scpShell.Close();
        //}

        #region IFalconLibrary Members

        /// <summary>
        /// Returns the name of this library component.  Implementation of FalconGlobal.IFalconLibrary.FalconComponentName.
        /// </summary>
        public string FalconComponentName
        {
            get { return "Falcon JTAG Programmer"; }
        }

        /// <summary>
        /// Returns the version of this library component.  Implementation of FalconGlobal.IFalconLibrary.FalconComponentVersion.
        /// </summary>
        public string FalconComponentVersion
        {
            get { return "Version 1.0.0"; }
        }

        /// <summary>
        /// Returns the name/version/copyright information of this library component.  Implementation of 
        /// FalconGlobal.IFalconLibrary.GetFalconComponentVersion().
        /// </summary>
        public string GetFalconComponentVersion()
        {
            return "Falcon JTAG Programmer 1.0.0 Copyright (c) 2010 PennState";
        }

        #endregion
    }
}
